package com.woniuxy.ptapp.app.controller;


import cn.hutool.core.text.AntPathMatcher;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.woniuxy.commons.util.BeanCopyUtil;
import com.woniuxy.commons.util.DateUtil;
import com.woniuxy.commons.util.Result;
import com.woniuxy.commons.util.WebUtil;
import com.woniuxy.ptapp.client.ClassesOrderClient;
import com.woniuxy.ptapp.client.param.ByClassesParam;
import com.woniuxy.ptapp.client.param.ClassesOrderDto;
import com.woniuxy.ptapp.common.config.AlipayConfig;
import com.woniuxy.ptapp.common.exception.EnumExceptionCode;
import com.woniuxy.ptapp.common.exception.ParamException;
import com.woniuxy.ptapp.common.exception.WoniuxyException;
import com.woniuxy.ptapp.infra.model.ClassesInfo;
import com.woniuxy.ptapp.infra.model.ClassesOrder;
import com.woniuxy.ptapp.infra.model.ClassesOrderInfo;
import com.woniuxy.ptapp.service.ClassesInfoService;
import com.woniuxy.ptapp.service.ClassesOrderService;
import com.woniuxy.ptapp.service.dto.ByClassesDto;
import io.seata.spring.annotation.GlobalTransactional;
import io.swagger.annotations.Api;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.crypto.Data;
import java.io.UnsupportedEncodingException;
import java.text.ParseException;
import java.util.*;

/**
 * <p>
 * 课程订单 前端控制器
 * </p>
 *
 * @author wangdong
 * @since 2022-07-30
 */

@RestController
public class ClassesOrderController implements ClassesOrderClient {
    @Resource
    ClassesOrderService classesOrderService;
    @Resource
    ClassesInfoService classesInfoService;
    @Resource
    RocketMQTemplate rocketMQTemplate;

    //下订单课程(约私教) 不代表支付
    @Override
    public Result<Boolean> Orders(ByClassesParam byClassesParam) {

        ByClassesDto byClassesDto = BeanCopyUtil.copyObject(byClassesParam, ByClassesDto.class);
        classesOrderService.Orders(byClassesDto);

        return Result.getInstance(Boolean.class).setMsg("下单成功");
    }


    @Override
    public void payClasses(String orderNumber) throws Exception {
        System.out.println("===进入支付宝支付=======");
        //判断订单是否存在
        ClassesOrder classesOrder = classesOrderService.getOne(new QueryWrapper<ClassesOrder>().eq("order_num", orderNumber));
        if (classesOrder == null) {
            throw new WoniuxyException(EnumExceptionCode.getClassesOrderFail.getCode(), EnumExceptionCode.getClassesOrderFail.getMessage());
        }
        //支付只能在订单状态为已完成的情况才可以支付
        if (classesOrder.getState() != 4) {
            throw new WoniuxyException(EnumExceptionCode.TheStateCantPay.getCode(), EnumExceptionCode.TheStateCantPay.getMessage());
        }
        //通过classId查询相关课程信息
        ClassesInfo classesInfo = classesInfoService.getOne(new QueryWrapper<ClassesInfo>().eq("id", classesOrder.getClassesId()));
        //判断课程是否存在
        if (classesInfo == null) {
            throw new WoniuxyException(EnumExceptionCode.getClaessIdFail.getCode(), EnumExceptionCode.getClaessIdFail.getMessage());
        }
        //获得初始化的AlipayClient
        AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id, AlipayConfig.merchant_private_key, "json", AlipayConfig.charset, AlipayConfig.alipay_public_key, AlipayConfig.sign_type);
        //设置请求参数
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        alipayRequest.setReturnUrl(AlipayConfig.return_url);
        alipayRequest.setNotifyUrl(AlipayConfig.notify_url);
        String classesName = classesInfo.getClassesName();
        //商户订单号，商户网站订单系统中唯一订单号，必填
        String out_trade_no = orderNumber;
        //付款金额，必填
        String total_amount = classesOrder.getPrice() + "";
        //订单名称，必填total
        String subject = classesName;
        //商品描述，可空
        String body = classesInfo.getClassesDetails();

        alipayRequest.setBizContent("{\"out_trade_no\":\"" + out_trade_no + "\","
                + "\"total_amount\":\"" + total_amount + "\","
                + "\"subject\":\"" + subject + "\","
                + "\"body\":\"" + body + "\","
                + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");

        //请求
        String result = alipayClient.pageExecute(alipayRequest).getBody();

        //输出
        WebUtil.getResponse().setContentType("text/html;charset=" + AlipayConfig.charset);

        WebUtil.getResponse().getWriter().write(result);//直接将完整的表单html输出到页面

        WebUtil.getResponse().getWriter().flush();

        Message<String> keys = MessageBuilder.withPayload(orderNumber).setHeader("KEYS", UUID.randomUUID())
                .build();
        rocketMQTemplate.syncSend("CheckPayState:Check", keys, 3000, 17);

    }

    @PostMapping("/notify")
    public void notify(HttpServletRequest request, HttpServletResponse resp) throws UnsupportedEncodingException {
        System.out.println("-------------进入异步回调---------------");
        Map<String, String> params = new HashMap<String, String>();
        Map<String, String[]> requestParams = request.getParameterMap();
        for (
                Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            //乱码解决，这段代码在出现乱码时使用
//            valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put(name, valueStr);
        }

        boolean signVerified = false; //调用SDK验证签名
        try {
            signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.alipay_public_key, AlipayConfig.charset, AlipayConfig.sign_type);
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }

        if (signVerified) {//验证成功
            //商户订单号
            String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");

            //支付宝交易号
            String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"), "UTF-8");

            //交易状态
            String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"), "UTF-8");
            System.out.println("交易状态" + trade_status);
            if (trade_status.equals("TRADE_FINISHED")) {
                //判断该笔订单是否在商户网站中已经做过处理
                //如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
                //如果有做过处理，不执行商户的业务程序
                System.out.println("进入订单是否完成");
                //注意：
                //退款日期超过可退款期限后（如三个月可退款），支付宝系统发送该交易状态通知
            } else if (trade_status.equals("TRADE_SUCCESS")) {
                //判断该笔订单是否在商户网站中已经做过处理
                //如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
                //如果有做过处理，不执行商户的业务程序
                System.out.println("进入订单支付成功");
                System.out.println("订单编号" + out_trade_no);
                //注意：
                //付款完成后，支付宝系统发送该交易状态通知
                System.out.println("------------------");
                System.out.println("支付成功");
                //支付成功后修改支付状态
                ClassesOrder classesOrder = classesOrderService.getOne(new QueryWrapper<ClassesOrder>().eq("order_num", out_trade_no));
                //成功进入了异步回调，订单编号是肯定在数据库里面的
                classesOrder.setState(1);
                //修改支付方式
                classesOrder.setPayment(0);
                boolean save = classesOrderService.saveOrUpdate(classesOrder);
                if (!save) {
                    throw new WoniuxyException(EnumExceptionCode.ChangeOrederStateFail.getCode(), EnumExceptionCode.ChangeOrederStateFail.getMessage());
                }

            }


        } else {//验证失败
            System.out.println("支付失败");

        }
    }

    //展示登录用户人的订单
    @Override
    public Result<List<ClassesOrderDto>> showClassesOrder() {
        List<ClassesOrderInfo> classesOrderInfos = classesOrderService.showClassesOrder();
        List<ClassesOrderDto> classesOrderDtos = BeanCopyUtil.copyList(classesOrderInfos, ClassesOrderDto.class);
        return Result.getInstanceList(ClassesOrderDto.class).setMsg("查询订单成功").setCode(200).setData(classesOrderDtos);
    }

    //点击接单
    @Override
    public Result takeOrder(Integer id) {
        classesOrderService.takeOrder(id);
        return Result.getInstance().setMsg("接单成功").setCode(200);
    }

    //点击拒单
    @Override
    public Result rejectionOrders(Integer id, String refuseReason) {
        System.out.println("开始拒单=================");
        classesOrderService.rejectionOrders(id, refuseReason);
        return Result.getInstance().setMsg("拒单成功").setCode(200);
    }

    @Override
    public Result<ClassesOrderDto> getClassesOrderById(Integer id) {
        ClassesOrder classesOrder = classesOrderService.getOne(new QueryWrapper<ClassesOrder>().eq("id", id));
        if (null == classesOrder) {
            throw new WoniuxyException(EnumExceptionCode.getClassesOrderFail.getCode(), EnumExceptionCode.getClassesOrderFail.getMessage());
        }
        ClassesOrderDto classesOrderDto = BeanCopyUtil.copyObject(classesOrder, ClassesOrderDto.class);
        return Result.getInstance(ClassesOrderDto.class).setCode(200).setMsg("查询订单成功").setData(classesOrderDto);
    }
    @GlobalTransactional(rollbackFor = Exception.class)
    @Override
    public Result changeOrderState(Integer id, Integer orderState, Integer payment, String payTime) {
        ClassesOrder classesOrder = classesOrderService.getOne(new QueryWrapper<ClassesOrder>().eq("id", id));
        if (null == classesOrder) {
            throw new WoniuxyException(EnumExceptionCode.getClassesOrderFail.getCode(), EnumExceptionCode.getClassesOrderFail.getMessage());
        }
        classesOrder.setState(orderState);
        classesOrder.setPayment(payment);
        classesOrder.setPayTime(payTime);
        boolean b = classesOrderService.saveOrUpdate(classesOrder);
        if (!b) {
            throw new WoniuxyException(EnumExceptionCode.ChangeOrederStateFail.getCode(), EnumExceptionCode.ChangeOrederStateFail.getMessage());
        }
        return Result.getInstance().setMsg("修改订单状态成功").setCode(200);
    }

    @Override
    public Result finishClassesOreder(Integer id) {
        classesOrderService.finishClassesOreder(id);
        return Result.getInstance().setMsg("确认上课订单成功").setCode(200);
    }

    @Override
    public Result studentCancelOrder(Integer id) {
        classesOrderService.studentCancelOrder(id);
        return Result.getInstance().setMsg("取消订单成功").setCode(200);
    }

    public static void main(String[] args) {
         AntPathMatcher apm = new AntPathMatcher();
        String str1 ="**/pt/notify";
        String str2="http://ii5gf9.natappfree.cc/pt/notify";
        System.out.println(apm.match(str1, str2));

    }

}

